/**
 * Custom validators
 */
$(function(){
	if($.validator){
		// Chinese Home phone validator
		$.validator.addMethod("ChineseHomephone", function(value, element) {
			return this.optional(element) || (/^(\d{3,4})-?\d{7,8}$/.test(value) && validCityCode(value));
		}, "格式为(区号-电话号码)");
		
		// Chinese Cellphone validator
		$.validator.addMethod("ChineseCellphone", function(value, element) {
			return this.optional(element) || /^(13[0-9]|15[0-9]|18[0-9])\d{8}$/.test(value);
		}, "手机号码格式不正确");
		
		// Round to 25 validator
		$.validator.addMethod("RoundingUnit25", function(value, element) {
			var amount = parseFloat(value);
			return this.optional(element) || (!isNaN(amount) && amount % 25 == 0 );
		}, "贷款额应该是25的倍数");
		
		// Round to 100 validator
		$.validator.addMethod("RoundingUnit100", function(value, element) {
			var amount = parseFloat(value);
			return this.optional(element) || (!isNaN(amount) && amount % 100 == 0 );
		}, "贷款额应该是100的倍数");
		
		// Chinese ID Card validator
		$.validator.addMethod("ChineseIDCard", function(value, element) {
			return this.optional(element) || validChineseIDCard(value);
		}, "无效的识别卡");
		
		// Age Above 18
		$.validator.addMethod("AgeAbove18", function(value, element) {
			var dob = extractDOBFromIDCard(value);
			return this.optional(element) || dob != null && ageFromDOB(dob) >= 18;
		}, "您必须是年满18岁或以上");
		
		
		// Validate file size
		$.validator.addMethod("validDocumentSize", function(value, element) {

			var valid = true;
			// Validate file size <8MB (only available to modern browsers)
			if(typeof(element.files) != 'undefined' &&
				element.files.length > 0){
				
				for(var i = 0; i < element.files.length; i++){
					// If any of the files exceeds the max size, validation fails
					if(typeof(element.files[i].size) != 'undefined' && element.files[i].size > 8*1024*1024){
						valid = false;
						break;
					}
				}
			}
			
			return this.optional(element) || valid;
		}, "文件大小应该小于8MB");
		
		// Validate file format
		window.acceptedFileExtensions = ['jpg', 'jpeg', 'pjpeg', 'gif', 'png', 'tiff', 'pdf']; 
		$.validator.addMethod("validDocumentType", function(value, element) {
			
			var fileNames = [value];
			
			// Validate all files selected on this input (only available to modern browsers)
			if(typeof(element.files) != 'undefined' &&
				element.files.length > 0){
				fileNames = [];
				for(var i = 0; i < element.files.length; i++){
					// Collect all file names
					if(typeof(element.files[i].name) != 'undefined'){
						fileNames.push(element.files[i].name);
					}
				}
			}
			
			var valid = true;
			for(var i = 0; i < fileNames.length; i++){
				var fileNameParts = fileNames[i].split("\.");
				var extension = fileNameParts[fileNameParts.length - 1].toLowerCase();
				if($.inArray(extension, acceptedFileExtensions) < 0){
					valid = false;
					break;
				}
			}
			
			return this.optional(element) || valid;
		}, "上传的文件格式错误");
		
		// Validate file format including excel files
		window.acceptedExcelExtensions = ['xls', 'xlsx'];
		$.validator.addMethod("validDocumentTypeExcel", function(value, element) {
			
			var fileNames = [value];
			
			// Validate all files selected on this input (only available to modern browsers)
			if(typeof(element.files) != 'undefined' &&
				element.files.length > 0){
				fileNames = [];
				for(var i = 0; i < element.files.length; i++){
					// Collect all file names
					if(typeof(element.files[i].name) != 'undefined'){
						fileNames.push(element.files[i].name);
					}
				}
			}
			
			var valid = true;
			for(var i = 0; i < fileNames.length; i++){
				var fileNameParts = fileNames[i].split("\.");
				var extension = fileNameParts[fileNameParts.length - 1].toLowerCase();
				if($.inArray(extension, acceptedFileExtensions) < 0 &&
						$.inArray(extension, acceptedExcelExtensions) < 0){
					valid = false;
					break;
				}
			}
			
			return this.optional(element) || valid;
		}, "上传的文件格式错误");
		
		
		// Validate username
		$.validator.addMethod("validUsername", function(value, element) {
			// It should have at least 2 chinese caracters or 4 if it contains enghlish chars 
            var re = new RegExp("^[^\\s><#!?$*%@\\^()\\[\\]\\{\\}\\;:\\.,\\\"'\\\/&\\+`~=\\|\\\\]{2,12}$");
            
            var chineseChars = "";
            if(value != null){
            	chineseChars = value.replace(/[a-zA-Z0-9_\\-]+/g, "");
            }
            
            return this.optional(element) || (re.test(value) && (value.length >= 4 || chineseChars.length >= 2));
        }, "");
		
		$.validator.addMethod(
			    "customDate",
			    function(value, element) {
			        // put your own logic here, this is just a (crappy) example
			        return this.optional(element) || value.match(/^\d\d\d\d\-\d\d?\-\d\d?$/);
			    },
			    "请输入以下格式的日期: yyyy-mm-dd."
			);
		
		// Validate numeric field is greater than other
		$.validator.addMethod("greaterThan", function(value, element, param) {
			
			value = parseFloat(value);
			var targetValue = parseFloat($(param).val());
            
			return this.optional(element) || !isNaN(value) && !isNaN(targetValue) && value >= targetValue;
		}, "的最大的值应为大于最低");
	}
});

// Chinese ID card validation function
// @author https://gist.github.com/foxwoods/1817822
function validChineseIDCard(id) {
    // 18位身份证号
    // 国家标准《GB 11643-1999》
    function rid18(id) {
        if(! /^\d{17}[\dxX]$/.test(id)) {
            return false;
        }
        var modcmpl = function(m, i, n) { return (i + n - m % i) % i; },
            f = function(v, i) { return v * (Math.pow(2, i-1) % 11); },
            s = 0;
        for(var i=0; i<17; i++) {
            s += f(+id.charAt(i), 18-i);
        }
        var c0 = id.charAt(17),
            c1 = modcmpl(s, 11, 1);
        return c0-c1===0 || (c0.toLowerCase()==='x' && c1===10);
    }
 
    // 15位身份证号
    // 2013年1月1日起将停止使用
    // http://www.gov.cn/flfg/2011-10/29/content_1981408.htm
    function rid15(id) {
        var pattern = /^[1-9]\d{5}(\d{2})(\d{2})(\d{2})\d{2}[\dxX]$/,
            matches, y, m, d, date;
        matches = id.match(pattern);
        if(matches == null)
        	return false;
        y = +('19' + matches[1]);
        m = +matches[2];
        d = +matches[3];
        date = new Date(y, m-1, d);
        return (date.getFullYear()===y && date.getMonth()===m-1 && date.getDate()===d);
    }
 
    return rid18(id); // || rid15(id); // We will only allow 18 digits ID cards 
}

/**
 * Given a chinese card number, extract date of birth from it
 */
function extractDOBFromIDCard(idCard){
	var matches = null;
	if(idCard.length == 15){
		var pattern = /^\d{6}(\d{2})(\d{2})(\d{2})/;
		matches = idCard.match(pattern);
	}else if(idCard.length == 18){
		var pattern = /^\d{6}(\d{4})(\d{2})(\d{2})/;
		matches = idCard.match(pattern);
	}
	if(matches != null){
		var y = +matches[1];
		var m = +matches[2];
		var d = +matches[3];
		return new Date(y, m-1, d);
    }
	return null;
}

/**
 * Given a DOB calculate the age of the person
 */
function ageFromDOB(birthDate){
	var today = new Date();
	var age = today.getFullYear() - birthDate.getFullYear();
	var m = today.getMonth() - birthDate.getMonth();
	if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
		age--;
	}
	return age;
}
function validCityCode(value){
	for(var i = 0; i < chineseCities.length; i++){
		var zip = chineseCities[i].zip;
        if(value.indexOf(zip) == 0)
        	return true;
	}
	return false;
}